package com.linln.modules.system.service.impl;

import com.linln.common.constant.HeadImgConst;
import com.linln.common.data.PageSort;
import com.linln.common.enums.StatusEnum;
import com.linln.common.utils.PathMappingUtil;
import com.linln.common.utils.UUIDUtil;
import com.linln.modules.system.domain.Dept;
import com.linln.modules.system.domain.User;
import com.linln.modules.system.repository.UserRepository;
import com.linln.modules.system.service.DeptService;
import com.linln.modules.system.service.UserService;
import org.apache.logging.log4j.util.Strings;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.persistence.criteria.*;
import java.io.File;
import java.util.*;

/**
 * @author 小懒虫
 * @date 2018/8/14
 */
@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private UserRepository userRepository;

    @Autowired
    private DeptService deptService;


    /**
     * 根据用户名查询用户数据
     *
     * @param username 用户名
     * @return 用户数据
     */
    @Override
    public User getByName(String username) {
        return userRepository.findByUsername(username);
    }

    @Override
    public User getByOpenId(String openId) {
        return userRepository.findByOpenId(openId);
    }

    @Override
    public User getByPhone(String phone) {
        return userRepository.findByPhone(phone);
    }

    /**
     * 用户名是否存在
     *
     * @param user 用户对象
     * @return 用户数据
     */
    @Override
    public Boolean repeatByUsername(User user) {
        Long id = user.getId() != null ? user.getId() : Long.MIN_VALUE;
        return userRepository.findByUsernameAndIdNot(user.getUsername(), id) != null;
    }

    @Override
    public Boolean repeatByPhone(User user) {
        Long id = user.getId() != null ? user.getId() : Long.MIN_VALUE;
        return userRepository.findByPhoneAndIdNot(user.getPhone(), id) != null;
    }

    /**
     * 根据用户ID获取用户信息
     *
     * @param id 用户ID
     */
    @Override
    public User getById(Long id) {
        return userRepository.findById(id).orElse(null);
    }

    /**
     * 获取分页列表数据
     *
     * @param user 实体对象
     * @return 返回分页数据
     */
    @Override
    @Transactional
    public Page<User> getPageList(User user) {
        // 创建分页对象
        PageRequest page = PageSort.pageRequest(Sort.Direction.ASC);

        // 使用Specification复杂查询
        return userRepository.findAll(new Specification<User>() {

            @Override
            public Predicate toPredicate(Root<User> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
                List<Predicate> preList = new ArrayList<>();
                if (user.getId() != null) {
                    preList.add(cb.equal(root.get("id").as(Long.class), user.getId()));
                }
                if (user.getUsername() != null) {
                    preList.add(cb.equal(root.get("username").as(String.class), user.getUsername()));
                }
                if (user.getNickname() != null) {
                    preList.add(cb.like(root.get("nickname").as(String.class), "%" + user.getNickname() + "%"));
                }
                if (user.getPhone() != null) {
                    preList.add(cb.like(root.get("phone").as(String.class), "%" + user.getPhone() + "%"));
                }
                if (user.getDept() != null) {
                    // 联级查询部门
                    Dept dept = user.getDept();
                    List<Long> deptIn = new ArrayList<>();
                    deptIn.add(dept.getId());
                    List<Dept> deptList = deptService.getListByPidLikeOk(dept.getId());
                    deptList.forEach(item -> deptIn.add(item.getId()));

                    Join<User, Dept> join = root.join("dept", JoinType.INNER);
                    CriteriaBuilder.In<Long> in = cb.in(join.get("id").as(Long.class));
                    deptIn.forEach(in::value);
                    preList.add(in);
                }

                // 数据状态
                if (user.getStatus() != null) {
                    preList.add(cb.equal(root.get("status").as(Byte.class), user.getStatus()));
                }

                Predicate[] pres = new Predicate[preList.size()];
                return query.where(preList.toArray(pres)).getRestriction();
            }

        }, page);
    }

    /**
     * 保存用户
     *
     * @param user 用户实体类
     */
    @Override
    public User save(User user) {
        return userRepository.save(user);
    }


    /**
     * @param user 用户
     * @param img  头像
     * @return
     */
    @Override
    public User saveAndImg(User user, MultipartFile img) {
        if (img != null) {
            //如果原来就有头像 那么先删除原来的
            if (!Strings.isBlank(user.getHeadImg()) && !HeadImgConst.DEFAULTHEADIMG.equals(user.getHeadImg())) {
                File file = new File(PathMappingUtil.getPath(PathMappingUtil.IMGPATH, user.getHeadImg()));
                file.delete();
            }
            user.setHeadImg(PathMappingUtil.saveImg(PathMappingUtil.IMGPATH, PathMappingUtil.IMGPATHMAPPING, img));
        }
        return userRepository.save(user);
    }


    /**
     * 修改用户信息 哪一个有值修改哪个  其中phone，realName，cardId，birthday，sex  一旦修改过后就不能再修改了
     *
     * @param headImg      用户头像
     * @param userName 用户名
     * @param phone    用户手机号码
     * @param realName 用户真实姓名
     * @param cardId   证件号码
     * @param birthday 用户生日
     * @param sex      性别 1男 2女
     * @return
     */
    @Override
    public void updateUserInfo(String headImg, String userName, String phone, String realName, String cardId, String birthday, Byte sex, Long userId) {
        User user = this.getById(userId);
        //头像
        if (Strings.isNotBlank(headImg)) {
            //如果原来就有头像 并且不是默认头像 那么先删除原来的
            String path = PathMappingUtil.formatMapping(headImg);
            if (!HeadImgConst.DEFAULTHEADIMG.equals(path)) {
                File file = new File(PathMappingUtil.getPath(PathMappingUtil.IMGPATH, path));
                file.delete();
            }
            user.setHeadImg(path);
        }
        //用户名
        user.setUsername(userName);

        //其他的属性只能修改一次 原来有值的话 那么就不能再修改了

        //如果phone不为空 并且数据库中的也不为空
        if (Strings.isNotBlank(realName) && Strings.isBlank(user.getNickname())) {
            user.setNickname(realName);
        }
        if (Strings.isNotBlank(cardId) && Strings.isBlank(user.getIdcard())) {
            user.setIdcard(cardId);
        }
        if (Strings.isNotBlank(birthday) && Strings.isBlank(user.getBirthday())) {
            user.setBirthday(birthday);
        }
        if (sex != null && user.getSex() == null) {
            user.setSex(sex);
        }
        userRepository.save(user);
    }

    /**
     * 保存用户列表
     *
     * @param userList 用户实体类
     */
    @Override
    @Transactional
    public List<User> save(List<User> userList) {
        return userRepository.saveAll(userList);
    }

    /**
     * 状态(启用，冻结，删除)/批量状态处理
     */
    @Override
    @Transactional
    public Boolean updateStatus(StatusEnum statusEnum, List<Long> ids) {
        // 联级删除与角色之间的关联
        if (statusEnum == StatusEnum.DELETE) {
            if(ids.size()>0){
                userRepository.delWxOppid(ids);
            }
            return userRepository.deleteByIdIn(ids) > 0;
        }
        return userRepository.updateStatus(statusEnum.getCode(), ids) > 0;
    }

    @Override
    @Transactional
    public boolean delUserById(Long userId) {
        try {
            userRepository.deleteById(userId);
            return true;
        } catch (Exception e) {
            return false;
        }
    }




}
